package com.ff.xyh.front.service.impl;

import com.ff.xyh.common.entity.message.RoomMessage;
import com.ff.xyh.common.entity.post.*;
import com.ff.xyh.common.entity.result.ResultCode;
import com.ff.xyh.common.entity.result.ResultMessage;
import com.ff.xyh.common.entity.result.ResultObject;
import com.ff.xyh.common.entity.userfront.FrontUser;
import com.ff.xyh.common.entity.userfront.UserBlacker;
import com.ff.xyh.common.qo.message.RoomMessageQuery;
import com.ff.xyh.common.utils.MinioUtils;
import com.ff.xyh.common.utils.CommonUtil;
import com.ff.xyh.common.vo.message.ActionTypeAndRoomMessage;
import com.ff.xyh.common.vo.message.RoomMessageVo;
import com.ff.xyh.common.vo.post.*;
import com.ff.xyh.common.qo.post.PostShopQuery;
import com.ff.xyh.common.qo.post.PostTravelQuery;
import com.ff.xyh.common.vo.user.UserBaseInfo;
import com.ff.xyh.feign.client.message.RoomMessageClient;
import com.ff.xyh.feign.client.minio.MinioClient;
import com.ff.xyh.feign.client.post.*;
import com.ff.xyh.feign.client.userfront.FrontBlackerClient;
import com.ff.xyh.feign.client.userfront.FrontUserClient;
import com.ff.xyh.feign.config.MyRabbitConfigProperties;
import com.ff.xyh.front.config.PostRabbitConfig;
import com.ff.xyh.front.service.PostFeignService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Auther FF
 * @Date 2022年 11月 25日
 * @Time 22:10
 */
@Service
public class PostFeignServiceImpl implements PostFeignService {

    @Autowired
    private PostClient postClient;

    @Autowired
    private PostDeleteClient postDeleteClient;

    @Autowired
    private PostImgClient postImgClient;

    @Autowired
    private PostJoinerClient postJoinerClient;

    @Autowired
    private PostReplyClient postReplyClient;

    @Autowired
    private PostRoomClient postRoomClient;

    @Autowired
    private RoomMessageClient roomMessageClient;

    @Autowired
    private FrontUserClient userClient;

    @Autowired
    private FrontBlackerClient blackerClient;

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Override
    public ResultObject getPostShopCondition(PostShopQuery postShopQuery) {
        return postClient.getPostShopPageCondition(postShopQuery);
    }

    @Override
    public ResultObject getPostTravelCondition(PostTravelQuery postTravelQuery) {
        return postClient.getPostTravelPageCondition(postTravelQuery);
    }

    @Override
    public ResultObject getPost(String id, int type) {

        if (type == 0){
            return ResultObject.error().message(ResultMessage.UNKNOWN_TYPE);
        } else if (type == 1) {
            PostShopVo postVo = getPostShopVo(id, type);
            if (postVo == null)
                return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
            else
                return ResultObject.ok().data("data", postVo);

        } else if (type == 2) {
            PostTravelVo postVo = getPostTravelVo(id, type);
            if (postVo == null)
                return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
            else
                return ResultObject.ok().data("data", postVo);
        } else if (type == 3) {
            return ResultObject.error().message("未开放");
        } else {
            return ResultObject.error().message(ResultMessage.UNKNOWN_TYPE);
        }
    }

    @Override
    public ResultObject addPostShop(PostShopVo postShopVo) {
//        int level = postShopVo.getLevel();
        List<PostImg> postImgs = postShopVo.getPostImgList();
        PostShop post = postShopVo.getPost();
//        files/img-files/post/1/c195c208-32fa-44af-80a7-2b09542597f7/cover.png

        String coverUrl = postImgs.get(0).getImgUrl();
        coverUrl = coverUrl.substring(0, coverUrl.lastIndexOf('/')) + "/cover.png";
        System.out.println(coverUrl);
        post.setCoverUrl(coverUrl);

        ResultObject resultObject = postClient.insertPostShop(postShopVo);
        System.out.println(resultObject);
        // 不成功
        if (!resultObject.getCode().equals(ResultCode.SUCCESS_CODE)) {
            // TODO 先删除图片 再返回
            return resultObject;
        }

        // 删掉第一张
        postImgs.remove(0);
        PostShop savedPost = CommonUtil.getDataInResultObject(resultObject, PostShop.class);
        // 帖子保存成功
        if (savedPost != null) {
            // 存在照片集
            if (savedPost.getIfImgs() == 1 && postImgs != null && postImgs.size() > 1){
                System.out.println("帖子有照片集");
                for (PostImg postImg : postImgs) {
                    postImg.setPostId(savedPost.getId());
                    postImg.setPostType(1);
//                postImg.getImg    Url() // 此项不可为没设置
                    if (! StringUtils.isEmpty(postImg.getImgUrl())) {
                        // 发送消息让监听器访问feign客户端
                        rabbitTemplate.convertAndSend(PostRabbitConfig.Exchange_Post, PostRabbitConfig.Routing_Key_PostImg, postImg);
                    }
                }
            }
            PostRoom postRoom = new PostRoom();
            postRoom.setPostType(1).setPostId(savedPost.getId()).setUserId(savedPost.getUserId());
            PostRoom savedPostRoom = CommonUtil.getDataInResultObject(postRoomClient.insertPostRoom(postRoom), PostRoom.class);
            if (savedPostRoom != null) {
                return ResultObject.ok()
                        .data("data", savedPost)
                        .data("room", savedPostRoom);
            } else {
                postClient.deletePostByIdAndType(savedPost.getId(), 1);
                return ResultObject.error()
                        .data("data", savedPost.setId(""))
                        .message("群聊创建失败，请重新发帖");
            }
        } else
            return ResultObject.error().message(ResultMessage.FAILED_TO_INSERT);
    }

    @Override
    public ResultObject addPostTravel(PostTravelVo postTravelVo) {

        List<PostImg> postImgs = postTravelVo.getPostImgList();
        PostTravel savedPost = CommonUtil.getDataInResultObject(postClient.insertPostTravel(postTravelVo), PostTravel.class);

        if (savedPost != null) {
            // 存在照片集
            if (savedPost.getIfImgs() == 1 && postImgs != null && postImgs.size() > 0) {
                System.out.println("帖子有照片集");
                for (PostImg postImg : postImgs) {
                    postImg.setPostId(savedPost.getId());
                    postImg.setPostType(2);
                    if (!StringUtils.isEmpty(postImg.getImgUrl())) {
                        // 发送消息让监听器访问feign客户端
                        rabbitTemplate.convertAndSend(
                                PostRabbitConfig.Exchange_Post,
                                PostRabbitConfig.Routing_Key_PostImg,
                                postImg);
                    }
                }
            }
            PostRoom postRoom = new PostRoom();
            postRoom.setPostType(2).setPostId(savedPost.getId()).setUserId(savedPost.getUserId());
            PostRoom savedPostRoom = CommonUtil.getDataInResultObject(postRoomClient.insertPostRoom(postRoom), PostRoom.class);
            if (savedPostRoom != null) {
                return ResultObject.ok()
                        .data("data", savedPost)
                        .data("room", savedPostRoom);
            } else {
                postClient.deletePostByIdAndType(savedPost.getId(), 1);
                return ResultObject.error()
                        .data("data", savedPost.setId(""))
                        .message("群聊创建失败，请重新发帖");
            }
        } else
            return ResultObject.error().message(ResultMessage.FAILED_TO_INSERT);
    }

    @Override
    public ResultObject updatePostShop(PostShopVo postVo, HttpServletRequest request) {
        boolean isImgChangedSuccessful = false;
        boolean isPostChangedSuccessful = false;
        String isImgChanged = request.getHeader("isImgChanged");
//        String isImgChanged = "1"; // TODO
        PostShop changedPost = postVo.getPost();
        List<PostImg> postImgs = postVo.getPostImgList();

        PostShop savedPost = CommonUtil.getDataInResultObject(postClient.updatePostShop(changedPost), PostShop.class);
        if (savedPost != null) {
            isPostChangedSuccessful = true;
            if (!StringUtils.isEmpty(isImgChanged) && isImgChanged.contains("1")) {
                for (PostImg postImg : postImgs) {
                    System.out.println(postImg);
                    postImg.setPostId(changedPost.getId());
                    postImg.setPostType(1);
                }
                // 删除原数据库照片集信息成功
                ResultObject deleteResult = postImgClient.deletePostImgsByPostIdAndType(changedPost.getId(), 1);
                if (deleteResult.getCode().equals(ResultCode.SUCCESS_CODE) || deleteResult.getMessage().equals(ResultMessage.NO_SUCH_OBJECT)) {
                    if (postImgClient.insertPostImgs(postImgs).getCode().equals(ResultCode.SUCCESS_CODE))
                        isImgChangedSuccessful = true;
                }
            }
        }
        if (isPostChangedSuccessful) {
            if (isImgChangedSuccessful)
                return ResultObject.ok().data("data", savedPost).data("items", postImgs);
            else
                return ResultObject.ok().data("data", savedPost);
        } else {
            return ResultObject.error().message(ResultMessage.FAILED_TO_UPDATE);
        }
    }

    @Override
    public ResultObject updatePostTravel(PostTravelVo postVo, HttpServletRequest request) {
        boolean isImgChangedSuccessful = false;
        boolean isPostChangedSuccessful = false;
        String isImgChanged = request.getHeader("isImgChanged");
        PostTravel changedPost = postVo.getPost();
        List<PostImg> postImgs = postVo.getPostImgList();

        PostTravel savedPost = CommonUtil.getDataInResultObject(postClient.updatePostTravel(changedPost), PostTravel.class);
        if (savedPost != null) {
            isPostChangedSuccessful = true;
            if (!StringUtils.isEmpty(isImgChanged) && isImgChanged.contains("1")) {
                for (PostImg postImg : postImgs) {
                    System.out.println(postImg);
                    postImg.setPostId(changedPost.getId());
                    postImg.setPostType(1);
                }
                // 删除原数据库照片集信息成功
                ResultObject deleteResult = postImgClient.deletePostImgsByPostIdAndType(changedPost.getId(), 1);
                if (deleteResult.getCode().equals(ResultCode.SUCCESS_CODE) || deleteResult.getMessage().equals(ResultMessage.NO_SUCH_OBJECT)) {
                    if (postImgClient.insertPostImgs(postImgs).getCode().equals(ResultCode.SUCCESS_CODE))
                        isImgChangedSuccessful = true;
                }
            }
        }

        if (isPostChangedSuccessful) {
            if (isImgChangedSuccessful)
                return ResultObject.ok().data("data", savedPost).data("items", postImgs);
            else
                return ResultObject.ok().data("data", savedPost);
        } else {
            return ResultObject.error().message(ResultMessage.FAILED_TO_UPDATE);
        }
    }

    @Override
    public ResultObject addPostReply(PostReply postReply) {
        return postReplyClient.insertPostReply(postReply);
    }
    @Override
    public ResultObject deletePostReply(String id) {
        return postReplyClient.deletePostReplyById(id);
    }

    @Override
    public ResultObject uploadPostCover(MultipartFile multipartFile, HttpServletRequest request) {
        String uuid = request.getHeader("uuid");
        String type = request.getHeader("type"); // 必须有
        System.out.println(multipartFile.getOriginalFilename());
//        若 没有type 或 上传的文件不是图片 则返回错误
        if (StringUtils.isEmpty(type) || (! multipartFile.getContentType().contains("image")))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        // 没有上传过 也就没有uuid
        if (StringUtils.isEmpty(uuid)) {
            uuid = UUID.randomUUID().toString();
        }
//        /img-files/(shop/travel)/uuid/cover.png
        String pathAndFilename = "/img-files/post/%s/%s/cover%s";
        pathAndFilename = String.format(pathAndFilename, type, uuid,
                MinioUtils.getFileSuffix(multipartFile.getOriginalFilename()));

        return minioClient.uploadFileToPath(multipartFile, pathAndFilename);
    }

    @Override
    public ResultObject uploadPostCover(MultipartFile multipartFile, String type, String uuid) {
//        若 没有type 或 上传的文件不是图片 则返回错误

        if (StringUtils.isEmpty(type))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);

        // 没有上传过 也就没有uuid
        if (StringUtils.isEmpty(uuid)) {
            uuid = UUID.randomUUID().toString();
        }
//        /img-files/(shop/travel)/uuid/cover.png
        String pathAndFilename = "/img-files/post/%s/%s/cover%s";

        pathAndFilename = String.format(pathAndFilename, type, uuid,
                MinioUtils.getFileSuffix(multipartFile.getOriginalFilename()));

        return minioClient.uploadFileToPath(multipartFile, pathAndFilename);
    }

    @Override
    public ResultObject uploadPostImg(MultipartFile file, String type, String uuid) {
        System.out.println(file.getContentType());
        System.out.println(file.getOriginalFilename());
        // 根据文件名判断是否图片类型
        if(! CommonUtil.regFileNameIsImage(file.getOriginalFilename()))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        // 两个参数缺一不可
        if (StringUtils.isEmpty(type))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);

        String uploadPath = "/img-files/post/%s/%s/";

        if (StringUtils.isEmpty(uuid)) {
            uuid = UUID.randomUUID().toString();
            uploadPath = String.format(uploadPath, type, uuid) + "cover.png";
        } else {
//          /img-files/shop/uuid/xxx.png
            uploadPath = String.format(uploadPath, type, uuid) + file.getOriginalFilename();
        }


        return minioClient.uploadFileToPath(file, uploadPath);
    }

    //    @Override
//    public ResultObject uploadPostImgs(MultipartFile[] multipartFiles, HttpServletRequest request) {
//
//        // 没有传入或传入超过8个文件 因为封面自身一张，总共可以9张
//        if (multipartFiles.length < 1 || multipartFiles.length > 8)
//            return ResultObject.error().message(ResultMessage.ERROR_ARG);
//        // 遍历检查文件类型
//        for (MultipartFile multipartFile : multipartFiles)
//            if(! multipartFile.getContentType().contains("image"))
//                return ResultObject.error().message(ResultMessage.ERROR_ARG);
//
//        String type = request.getHeader("type");
//        String uuid = request.getHeader("uuid");
//        // 两个参数缺一不可
//        if (StringUtils.isEmpty(type) || StringUtils.isEmpty(uuid))
//            return ResultObject.error().message(ResultMessage.ERROR_ARG);
//
////        /img-files/shop/uuid/
//        String uploadPath = "/img-files/post/%s/%s/";
//        uploadPath = String.format(uploadPath, type, uuid);
////        if (multipartFiles.length == 1)
////            return minioClient.uploadFileToPath(multipartFiles[0],
////                    uploadPath+"1"+MinioUtils.getFileSuffix(multipartFiles[0].getOriginalFilename()));
////        else
//        return minioClient.uploadFiles(multipartFiles, uploadPath);
//    }
    @Override
    public ResultObject uploadPostImgs(MultipartFile[] multipartFiles, String type, String uuid) {

        // 没有传入或传入超过8个文件 因为封面自身一张，总共可以9张
        if (multipartFiles.length < 1 || multipartFiles.length > 8)
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        // 遍历检查文件类型
        for (MultipartFile multipartFile : multipartFiles)
            if(! multipartFile.getContentType().contains("image"))
                return ResultObject.error().message(ResultMessage.ERROR_ARG);

        // 两个参数缺一不可
        if (StringUtils.isEmpty(type) || StringUtils.isEmpty(uuid))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);

//        /img-files/shop/uuid/
        String uploadPath = "/img-files/post/%s/%s/";
        uploadPath = String.format(uploadPath, type, uuid);
//        if (multipartFiles.length == 1)
//            return minioClient.uploadFileToPath(multipartFiles[0],
//                    uploadPath+"1"+MinioUtils.getFileSuffix(multipartFiles[0].getOriginalFilename()));
//        else
        return minioClient.uploadFiles(multipartFiles, uploadPath);
    }

    /**
     * 修改照片集文件
     * 先删除原有目录 再将文件添加
     */
    @Override
    public ResultObject uploadChangedImgs(MultipartFile[] multipartFiles, HttpServletRequest request) {

        String isImgChanged = request.getHeader("isImgChanged");
        if (StringUtils.isEmpty(isImgChanged) || !isImgChanged.contains("1")) {
            return ResultObject.error().message("请求头中没有指定变量");
        }

        // 没有传入或传入超过8个文件 因为封面自身一张，总共可以9张
        if (multipartFiles.length < 1 || multipartFiles.length > 8)
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        // 遍历检查文件类型
        for (MultipartFile multipartFile : multipartFiles)
            if(! multipartFile.getContentType().contains("image"))
                return ResultObject.error().message(ResultMessage.ERROR_ARG);

        String type = request.getHeader("type");
        String uuid = request.getHeader("uuid");

        // 两个参数缺一不可
        if (StringUtils.isEmpty(type) || StringUtils.isEmpty(uuid))
            return ResultObject.error().message(ResultMessage.ERROR_ARG);

        String uploadPath = "/img-files/post/%s/%s/";
        uploadPath = String.format(uploadPath, type, uuid);

        ResultObject deleteResult = minioClient.deleteFilesInDir(uploadPath);

        if (deleteResult.getCode() == ResultCode.SUCCESS_CODE){
//            List<Object> oldItems = (List<Object>) MyStringUtil.getItemsInResultObject(deleteResult);
            return minioClient.uploadFiles(multipartFiles, uploadPath);
        } else {
            return ResultObject.error().message("旧图片上传失败，停止新图片上传");
        }
    }

    @Override
    public ResultObject deletePostByUser(PostDelete postDelete) {
        if (postDelete == null) {
            return ResultObject.error().message("参数为空");
        }
        Integer postType = postDelete.getPostType();
        String postId = postDelete.getPostId();

        if (postType == 0) {
            return ResultObject.error().message(ResultMessage.UNKNOWN_TYPE);
        } else if (postType == 1){
            PostShop post = CommonUtil.getDataInResultObject(postClient.getPostShopById(postId), PostShop.class);
            if (post != null) {
                post.setPostStatus(-1);
                post = CommonUtil.getDataInResultObject(postClient.updatePostShop(post), PostShop.class);
                if (post != null) {
                    postDelete = CommonUtil.getDataInResultObject(
                            postDeleteClient.insertPostDelete(postDelete), PostDelete.class);
                    if (postDelete != null) {
                        return ResultObject.ok().data("data", postDelete);
                    } else {
                        return ResultObject.error().message("帖子删除成功但是删除记录添加失败");
                    }
                } else {
                    return  ResultObject.error().message(ResultMessage.OBJECT_EXISTS_BUT_FAILED_TO_UPDATE);
                }
            } else {
                return  ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
            }
        } else if (postType == 2){
            PostTravel post = CommonUtil.getDataInResultObject(postClient.getPostTravelById(postId), PostTravel.class);
            if (post != null) {
                post.setPostStatus(-1);
                post = CommonUtil.getDataInResultObject(postClient.updatePostTravel(post), PostTravel.class);
                if (post != null) {
                    postDelete = CommonUtil.getDataInResultObject(
                            postDeleteClient.insertPostDelete(postDelete), PostDelete.class);
                    if (postDelete != null) {
                        return ResultObject.ok().data("data", postDelete);
                    } else {
                        return ResultObject.error().message("帖子删除成功但是删除记录添加失败");
                    }
                } else {
                    return  ResultObject.error().message(ResultMessage.OBJECT_EXISTS_BUT_FAILED_TO_UPDATE);
                }
            } else {
                return  ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
            }
        } else {
            return ResultObject.error().message(ResultMessage.UNKNOWN_TYPE);
        }

    }

    @Override
    public ResultObject deleteImgInPath(String path) {
        if (! path.startsWith("files") || ! path.contains(".")) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        return minioClient.deleteFile(path);
    }

    @Override
    public ResultObject deleteImgsInPath(String path) {
        if (! path.startsWith("files") || path.contains(".")) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        return minioClient.deleteFilesInDir(path);
    }

    @Override
    public ResultObject failedAdd(String postId, String type, String uuid) {
        if (! StringUtils.isEmpty(postId)) {
            int postType = Integer.parseInt(type);
            if (postType < 1)
                return ResultObject.error().message(ResultMessage.ERROR_ARG);
            else
                postClient.deletePostByIdAndType(postId, postType);
        }
        String path = "/img-files/post/%s/%s";
        path = String.format(path, type, uuid);
        minioClient.deleteFilesInDir(path);
        return ResultObject.ok();
    }


    @Override
    public ResultObject addPostJoiner(PostJoiner joiner) {
        String postId = joiner.getPostId();
        String userId = joiner.getUserId();
        Integer postType = joiner.getPostType();
        Integer joinerNumber = joiner.getNumber();

        if (StringUtils.isEmpty(postId)
                || StringUtils.isEmpty(userId)
                || joinerNumber == null || joinerNumber == 0
                || postType == null || postType == 0) {

            // 参数非法
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }

        // 判断用户是否存在
        FrontUser user = CommonUtil.getDataInResultObject(
                userClient.getUserBaseInfoById(userId),
                FrontUser.class);
        if (user == null) {
            // 参数非法
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }

        List<PostJoiner> postJoinerList = CommonUtil.getItemsInResultObject(
                postJoinerClient.getEffectivePostJoinersWithPostIdAndPostType(
                        postId, postType),
                PostJoiner.class);
        // 有参与者
        boolean hasJoiner = (postJoinerList != null && ! postJoinerList.isEmpty());

        if (hasJoiner) {
            List<PostJoiner> collect = postJoinerList.stream().filter(existJoiner -> userId.equals(existJoiner.getUserId())).collect(Collectors.toList());
            if (collect != null && !collect.isEmpty()) {  // 参与过了
                return ResultObject.error().message("用户已申请过, 重新申请请先退出");
            }
        }

        Integer restNumber = 0;
        if (postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId), PostShop.class);
            if (post == null || post.getPostStatus() != 0)
                return ResultObject.error().message(ResultMessage.FAILED_TO_INSERT);
            if (userId.equals(post.getUserId()))
                // 参数非法
                return ResultObject.error().message(ResultMessage.ERROR_ARG);
            // 是否被拉黑
            if (CommonUtil.getDataInResultObject(
                    blackerClient.getUserBlack(userId, post.getUserId()),
                    UserBlacker.class) != null)
                // 参数非法
                return ResultObject.error().message("请求失败，您已被对方拉黑");

            Integer postTotal = post.getTotal();
            if (joinerNumber > post.getLeastOnce()) {
                return ResultObject.error().message("申请的数量太少了，申请失败，最少需要 " + post.getLeastOnce());
            }
            if ( postTotal  - post.getUserNumber() < 0) { // 帖子参数有问题
                return ResultObject.error().message("帖子参数有问题，申请失败");
            } else if (hasJoiner) { // 参数没问题 有参与者
                Integer joinersTotal = 0; // 参与者数量总和
                for (PostJoiner postJoiner : postJoinerList) {
                    joinersTotal += postJoiner.getNumber();
                }
                // 剩余数量
                restNumber = postTotal - post.getUserNumber() - joinersTotal;
                // 数量不足
                if (restNumber < joinerNumber) {
                    // 帖子和已参与者的数量有问题
                    if (restNumber < 0) {
                        return ResultObject.error().message("帖子参数有问题，申请失败");
                    }
                    return ResultObject.error().message("申请的数量太多了，申请失败，最多可 " + restNumber);
                }

                // 剩余数量刚好为参与者需要的数量时 得将帖子状态改为1
                if (restNumber == joinerNumber
                        &&
                        post.getPostStatus() != 0) {
                    postClient.updatePostShop(
                            post.setPostStatus(1).setGmtModified(new Date()));
                }

            }
        } else if (postType == 2) {
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId), PostTravel.class);

            if (post == null || post.getPostStatus() != 0)
                return ResultObject.error().message(ResultMessage.FAILED_TO_INSERT);
            if (userId.equals(post.getUserId()))
                // 参数非法
                return ResultObject.error().message(ResultMessage.ERROR_ARG);
            // 是否被拉黑
            if (CommonUtil.getDataInResultObject(
                    blackerClient.getUserBlack(userId, post.getUserId()),
                    UserBlacker.class) != null)
                // 参数非法
                return ResultObject.error().message("请求失败，您已被对方拉黑");

            Integer postTotalMin = post.getTotalMin();
            Integer postTotalMax = post.getTotalMax();
            Integer userNumber = post.getUserNumber();
            if ( ( postTotalMax  - userNumber ) < 0) { // 帖子参数有问题
                return ResultObject.error().message("帖子参数有问题，申请失败");
            } else if (hasJoiner) { // 参数没问题 有参与者
                Integer joinersTotal = 0; // 参与者数量总和
                for (PostJoiner postJoiner : postJoinerList) {
                    joinersTotal += postJoiner.getNumber();
                }
                // 剩余数量
                restNumber = postTotalMax - userNumber - joinersTotal;
                // 数量不足
                if (restNumber < joinerNumber) {
                    // 帖子和已参与者的数量有问题
                    if (restNumber < 0) {
                        return ResultObject.error().message("帖子参数有问题，申请失败");
                    }
                    return ResultObject.error().message("申请的数量太多了，申请失败");
                }
                // 参与者大于最少人数 并且 帖子状态不为1 时 将帖子状态设为1
                if ((userNumber + joinersTotal + joinerNumber )
                        > postTotalMin
                        &&
                        post.getPostStatus() != 0) {
                    postClient.updatePostTravel(
                            post.setPostStatus(1).setGmtModified(new Date()));
                }
            }
        }
        ResultObject result = postJoinerClient.insertPostJoiner(joiner);
        PostJoiner savedJoiner = CommonUtil.getDataInResultObject(result, PostJoiner.class);
        if (savedJoiner != null) {
            // 申请成功
//            用户在线时
            if (redisTemplate.hasKey("online" + savedJoiner.getUserId())) {
                String userMessageRoutingKey = (String) redisTemplate.opsForValue().get("online" + savedJoiner.getUserId());
                if (!StringUtils.isEmpty(userMessageRoutingKey)) {
                    PostRoom room = CommonUtil.getDataInResultObject(
                            postRoomClient.getPostRoomWithPostIdAndType(
                                    postId, postType), PostRoom.class);
                    if (room != null) {
                        // 将消息发送给用户的队列
                        rabbitTemplate.convertAndSend(
                                MyRabbitConfigProperties.EXCHANGE_DIRECT_USER,
                                userMessageRoutingKey,
                                ActionTypeAndRoomMessage.type(5).data(
                                        "message", new RoomMessageVo()
                                                .setRoomId(room.getId())
                                                .setUserId(userId)
                                ));
                    }
                }
            }
        }
        return result;
    }

    @Override
    public ResultObject hasPostJoiner(String postId, Integer postType, String userId) {
        PostJoiner joiner = CommonUtil.getDataInResultObject(
                postJoinerClient.getPostJoinerWithPostIdAndTypeAndUserId(
                        postId, postType, userId, false),
                PostJoiner.class);
        if (joiner == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
        return ResultObject.ok().data("data", joiner);
    }

    @Override
    public ResultObject changeJoinerUserNumber(String postId, Integer postType, String userId, Integer number) {
        if (StringUtils.isEmpty(postId)
                || StringUtils.isEmpty(userId)
                || postType == null || postType == 0) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        List<PostJoiner> joinerList = CommonUtil.getItemsInResultObject(
                postJoinerClient.getEffectivePostJoinersWithPostIdAndPostType(
                        postId, postType),
                PostJoiner.class);
        boolean hasJoiner = true;
        if (joinerList == null || joinerList.isEmpty()) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        Integer restNumber = 0;
        if ( postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId),
                    PostShop.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            if (post.getLeastOnce() > number)
                return ResultObject.error().message("数量太少，修改失败");

            // 只有未开始并且人数未满时，才允许修改数量
            // 不符合条件时，直接表示状态不允许修改
            if (post.getPostStatus() != 0) {
                return ResultObject.error().message("当前帖子状态不允许修改数量");
            }
            restNumber += post.getUserNumber();
            if (hasJoiner) {
                for (PostJoiner postJoiner : joinerList) {
                    if (userId.equals(postJoiner.getUserId())) {
                        continue;
                    }
                    restNumber += postJoiner.getNumber();
                }
            }
            restNumber = post.getTotal() - restNumber;
            if (restNumber < number) {
                if (restNumber < 0) { // 帖子参数有误
                    return ResultObject.error().message("帖子参数有问题，修改失败");
                }
                return ResultObject.error().message("数量不足，修改失败");
            }
        } else if (postType == 2) {
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId),
                    PostTravel.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 只有未开始并且人数未满时，才允许修改数量
            // 不符合条件时，直接表示状态不允许修改
            if (post.getPostStatus() != 0) {
                return ResultObject.error().message("当前帖子状态不允许修改数量");
            }
            restNumber += post.getUserNumber();
            if (hasJoiner) {
                for (PostJoiner postJoiner : joinerList) {
                    if (userId.equals(postJoiner.getUserId())) {
                        continue;
                    }
                    restNumber += postJoiner.getNumber();
                }
            }
            restNumber = post.getTotalMax() - restNumber;
            if (restNumber < number) {
                if (restNumber < 0) { // 帖子参数有误
                    return ResultObject.error().message("帖子参数有问题，修改失败");
                }
                return ResultObject.error().message("数量不足，修改失败");
            }
        } else {
            // 未知类型 参数错误
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }

        return postJoinerClient.changePostJoinerNumber(
                postId, postType, userId, number);
    }

    @Override
    public ResultObject deletePostJoiner(String postId, Integer postType, String userId) {
        if (StringUtils.isEmpty(postId)
                || StringUtils.isEmpty(userId)
                || postType == null || postType == 0) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        Integer status = 3;

        if ( postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId),
                    PostShop.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 拼单开始后不允许踢人
            if (post.getPostStatus() != 0 || post.getPostStatus() != 1) {
                return ResultObject.error().message("当前帖子状态不允许删除参与者");
            }
        } else if (postType == 2) {
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId),
                    PostTravel.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 拼单开始后不允许踢人
            if (post.getPostStatus() != 0 || post.getPostStatus() != 1) {
                return ResultObject.error().message("当前帖子状态不允许删除参与者");
            }
        } else {
            // 未知类型 参数错误
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        return postJoinerClient.changePostJoinerStatus(
                postId, postType, userId, status
        );
    }

    @Override
    public ResultObject cancelPostJoiner(String postId, Integer postType, String userId) {
        if (StringUtils.isEmpty(postId)
                || StringUtils.isEmpty(userId)
                || postType == null || postType == 0) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        Integer status = 4;

        if ( postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId),
                    PostShop.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 拼单开始后不允许退出
            if (post.getPostStatus() != 0 || post.getPostStatus() != 1) {
                return ResultObject.error().message("当前帖子状态不允许退出拼单");
            }
        } else if (postType == 2) {
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId),
                    PostTravel.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 拼单开始后不允许退出
            if (post.getPostStatus() != 0 || post.getPostStatus() != 1) {
                return ResultObject.error().message("当前帖子状态不允许退出拼单");
            }
        } else {
            // 未知类型 参数错误
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        return postJoinerClient.changePostJoinerStatus(
                postId, postType, userId, status
        );
    }

    /**
     * TODO 应该获取人数判断机制 将多余的申请删除
     * TODO 当用户在线时，需要将用户加入帖子对应群聊
     */
    @Override
    public ResultObject acceptPostJoiner(String postId, Integer postType, String userId) {
        if (StringUtils.isEmpty(postId)
                || StringUtils.isEmpty(userId)
                || postType == null || postType == 0) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        PostJoiner joiner = CommonUtil.getDataInResultObject(postJoinerClient.getPostJoinerWithPostIdAndTypeAndUserId(
                        postId, postType, userId, false),
                PostJoiner.class);
        if (joiner == null) {
            return ResultObject.error().message(ResultMessage.NO_SUCH_OBJECT);
        }
        if (joiner.getJoinerStatus() != 0) {
            return ResultObject.error().message("用户参与状态已被更改，无法接受该请求");
        }
        Integer status = -1; // 即将修改成该状态
        Integer joinerNumber = joiner.getNumber();
        Integer totalNumber = 0;// 已接受的joiner


        List<PostJoiner> joinerList = CommonUtil.getItemsInResultObject(
                postJoinerClient.getAcceptedPostJoinersWithPostIdAndPostType(
                        postId, postType),
                PostJoiner.class);

        if ( postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId),
                    PostShop.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 拼单开始后不允许踢人 也不允许退出
            if (post.getPostStatus() != 0) {
                return ResultObject.error().message("当前帖子状态不允许加入新的拼单者");
            }
            totalNumber += post.getUserNumber(); // 将用户需要的数量加入
            // 已接受的数量
            if (joinerList != null && !joinerList.isEmpty()) {
                for (PostJoiner postJoiner : joinerList) {
                    totalNumber += postJoiner.getNumber();
                }
            }
            if (post.getTotal() - totalNumber < joinerNumber)
                return ResultObject.error().message("超出预定数量，无法接受该请求");
            // 刚好满上 则将帖子状态修改
            if (post.getTotal() - totalNumber == joinerNumber)
                postClient.updatePostShop(post.setPostStatus(1));

        } else if (postType == 2) {
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId),
                    PostTravel.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
            // 拼单开始后不允许踢人 也不允许退出
            if (post.getPostStatus() != 0 || post.getPostStatus() != 1) {
                return ResultObject.error().message("当前帖子状态不允许加入新的拼单者");
            }
            totalNumber += post.getUserNumber(); // 将用户需要的数量加入
            if (joinerList != null && !joinerList.isEmpty()) {
                for (PostJoiner postJoiner : joinerList) {
                    totalNumber += postJoiner.getNumber();
                }
            }
            if (post.getTotalMax() - totalNumber < joinerNumber)
                return ResultObject.error().message("超出预定数量，无法接受该请求");
            // 刚好满上 则将帖子状态修改
            if (post.getTotalMax() - totalNumber == joinerNumber)
                postClient.updatePostTravel(post.setPostStatus(1));
        } else {
            // 未知类型 参数错误
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        ResultObject result = postJoinerClient.changePostJoinerStatus(
                postId, postType, userId, status);
        PostJoiner savedJoiner = CommonUtil.getDataInResultObject(result, PostJoiner.class);
        if (savedJoiner != null) {
            /** 以下是当用户被接受时才监听群聊消息的模式下才需要发消息进入群聊
             *      当前是用户申请和被接受则登录时自动监听消息
             */
//            // 用户在线时
//            if (redisTemplate.hasKey("online" + savedJoiner.getUserId())) {
//                String userMessageRoutingKey = (String) redisTemplate.opsForValue().get("online" + savedJoiner.getUserId());
//                if (!StringUtils.isEmpty(userMessageRoutingKey)) {
//                    PostRoom room = MyStringUtil.getDataInResultObject(
//                            postRoomClient.getPostRoomWithPostIdAndType(
//                                    postId, postType), PostRoom.class);
//                    if (room != null) {
//                        // 将消息发送给用户的队列
//                        rabbitTemplate.convertAndSend(
//                                MyRabbitConfigProperties.EXCHANGE_DIRECT_USER,
//                                userMessageRoutingKey,
//                                ActionTypeAndRoomMessage.type(5).data(
//                                        "message", new RoomMessageVo()
//                                                .setRoomId(room.getId())
//                                                .setUserId(userId)
//                                ));
//                    }
//                }
//            }
        }
        return result;
    }

    @Override
    public ResultObject refusePostJoiner(String postId, Integer postType, String userId) {
        if (StringUtils.isEmpty(postId)
                || StringUtils.isEmpty(userId)
                || postType == null || postType == 0) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        Integer status = 0;

        if ( postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId),
                    PostShop.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
        } else if (postType == 2) {
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId),
                    PostTravel.class);
            if (post == null) {
                return ResultObject.error().message("帖子不存在了");
            }
        } else {
            // 未知类型 参数错误
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        return postJoinerClient.changePostJoinerStatus(
                postId, postType, userId, status
        );
    }

    @Override
    public ResultObject isUserSpeakable(String postId, Integer postType, String userId) {
        if (StringUtils.isEmpty(postId)
            || postType == null || postType == 0
            || StringUtils.isEmpty(userId)) {
            return ResultObject.error().message(ResultMessage.ERROR_ARG);
        }
        boolean result = false;
        // 拼购帖
        if (postType == 1) {
            PostShop post = CommonUtil.getDataInResultObject(
                    postClient.getPostShopById(postId), PostShop.class);
            if (userId.equals(post.getUserId())) {
                result = true;
            } else { // 如果不是发帖人 那就有可能是接收了的参与者
                List<PostJoiner> joinerList = CommonUtil.getItemsInResultObject(postJoinerClient
                        .getAcceptedPostJoinersWithPostIdAndPostType(
                                postId, postType), PostJoiner.class);
                if (joinerList != null && !joinerList.isEmpty()) {
                    for (PostJoiner postJoiner : joinerList) {
                        if (userId.equals(postJoiner.getUserId())) {
                            result = true;
                        }
                    }
                }
            }
        } else if (postType == 2) { // 旅游帖
            PostTravel post = CommonUtil.getDataInResultObject(
                    postClient.getPostTravelById(postId), PostTravel.class);
            if (userId.equals(post.getUserId())) {
                result = true;
            } else { // 如果不是发帖人 那就有可能是接收了的参与者
                List<PostJoiner> joinerList = CommonUtil.getItemsInResultObject(postJoinerClient
                        .getAcceptedPostJoinersWithPostIdAndPostType(
                                postId, postType), PostJoiner.class);
                if (joinerList != null && !joinerList.isEmpty()) {
                    for (PostJoiner postJoiner : joinerList) {
                        if (userId.equals(postJoiner.getUserId())) {
                            result = true;
                        }
                    }
                }
            }
        }
        if (result)
            return ResultObject.ok().data("data", result);
        else
            return ResultObject.error().message("没有权限");
    }

    @Override
    public ResultObject getRoomMessage(long currentPage, long pageSize, String roomId, String messageId) {
        return roomMessageClient.getPageMessageInRoomBeforeMessage(
                        messageId, roomId, currentPage, pageSize);
    }

    @Override
    public ResultObject getRoomMessageListCondition(RoomMessageQuery roomMessageQuery) {
        ResultObject resultObject = roomMessageClient.getRoomMessageCondition(roomMessageQuery);
        List<RoomMessage> roomMessageList = CommonUtil.getItemsInResultObject(
                resultObject, RoomMessage.class);
        if (roomMessageList == null || roomMessageList.isEmpty()) {
            return resultObject;
        }
        List<RoomMessageVo> resultList = new ArrayList<>();
        List<String> userIds = roomMessageList.stream().map(
                RoomMessage::getUserId).collect(Collectors.toList());
        List<UserBaseInfo> userBaseInfoList = CommonUtil.getItemsInResultObject(
                userClient.getUserBaseInfosByIds(userIds), UserBaseInfo.class);
        if (userBaseInfoList == null || userBaseInfoList.isEmpty()) return resultObject;

        roomMessageList.forEach(roomMessage -> {
            RoomMessageVo roomMessageVo = new RoomMessageVo();
            BeanUtils.copyProperties(roomMessage, roomMessageVo);
            for (UserBaseInfo userBaseInfo : userBaseInfoList) {
                if (userBaseInfo.getId().equals(roomMessage.getUserId())) {
                    roomMessageVo.setUserNickname(userBaseInfo.getNickname());
                    roomMessageVo.setUserAvatar(userBaseInfo.getAvatar());
                    break;
                }
            }
            resultList.add(roomMessageVo);
        });
        return resultObject.changeList(resultList);
    }


    public PostShopVo getPostShopVo(String id, int type) {
        PostShop post = CommonUtil.getDataInResultObject(postClient.getPostShopById(id), PostShop.class);
        if (post != null) {
            PostShopVo result = new PostShopVo();

            int consumeLevel = CommonUtil.getConsumeLevel(post.getPrice() * post.getLeastOnce());

            PostVo postVo = getPostVo(id, type, consumeLevel, post.getUserId());

            BeanUtils.copyProperties(postVo, result);
            // post
            result.setPost(post);

            return result;
        } else {
            return null;
        }
    }

    public PostTravelVo getPostTravelVo(String id, int type) {
        PostTravel post = CommonUtil.getDataInResultObject(postClient.getPostTravelById(id), PostTravel.class);
        System.out.println(post);
        if (post != null) {
            PostTravelVo result = new PostTravelVo();

            int consumeLevel = CommonUtil.getConsumeLevel(post.getConsumePrice());

            PostVo postVo = getPostVo(id, type, consumeLevel, post.getUserId());

            BeanUtils.copyProperties(postVo, result);

            // post
            result.setPost(post);

            return result;
        } else {
            return null;
        }
    }

    public PostVo getPostVo(String id, int type, int consumeLevel, String userId) {
        PostVo postVo = new PostVo();

        // consumeLevel
        postVo.setLevel(consumeLevel);

        // UserBaseInfo
        System.out.println("UserBaseInfo");
        UserBaseInfo userBaseInfo = CommonUtil.getDataInResultObject(userClient.getUserBaseInfoById(userId), UserBaseInfo.class);
        if (userBaseInfo != null) {
            postVo.setUserBaseInfo(userBaseInfo);
        }
        // List<PostImg>
        System.out.println("List<PostImg>");
        List<PostImg> postImgList =
                CommonUtil.getItemsInResultObject(postImgClient.getPostImgsByIdAndType(id, type), PostImg.class);
        if (postImgList != null && ! postImgList.isEmpty()) {
            postVo.setPostImgList(postImgList);
        }

        // List<PostReplyVo>
        System.out.println("List<PostReplyVo>");
        List<PostReplyVo> replyVoList = CommonUtil.getItemsInResultObject(postReplyClient.getAllReplyVoByPostIdAndType(id, type), PostReplyVo.class);
        if (replyVoList != null && ! replyVoList.isEmpty()) {
            for (PostReplyVo postReplyVo : replyVoList) {
                // 一级回复
                PostReplyBaseInfo firstReply = postReplyVo.getFirstReply();
                UserBaseInfo fromFirstUser = CommonUtil.getDataInResultObject(userClient.getUserBaseInfoById(firstReply.getUserId()), UserBaseInfo.class);
                if (fromFirstUser != null) {
                    firstReply
                            .setFromUserAvatar(fromFirstUser.getAvatar())
                            .setFromUserNickname(fromFirstUser.getNickname());
                }
                // 子回复
                List<PostReplyBaseInfo> childReplies = postReplyVo.getChildReplies();
                if (childReplies != null) {
                    // 得到子回复中所有用户id
                    List<String> replyUserIds = childReplies.stream().map(PostReplyBaseInfo::getUserId).collect(Collectors.toList());

                    List<UserBaseInfo> replyUserBaseInfos = CommonUtil.getItemsInResultObject(userClient.getUserBaseInfosByIds(replyUserIds), UserBaseInfo.class);

                    childReplies.stream().forEach(postReplyBaseInfo -> {
                        String fromUserId = postReplyBaseInfo.getUserId();
                        String toUserId = postReplyBaseInfo.getToUserId();
                        if (replyUserBaseInfos != null) {

                            List<UserBaseInfo> fromUserBaseInfoList = replyUserBaseInfos.stream().filter(
                                    replyUserBaseInfo -> replyUserBaseInfo.getId().equals(fromUserId)
                            ).collect(Collectors.toList());
                            if (!fromUserBaseInfoList.isEmpty()) {

                                UserBaseInfo fromUser = fromUserBaseInfoList.get(0);
                                postReplyBaseInfo
                                        .setFromUserAvatar(fromUser.getAvatar())
                                        .setFromUserNickname(fromUser.getNickname()); // 发出者
                            } else {
                                // 如果是一级回复的用户
                                if (fromFirstUser != null && postReplyBaseInfo.getUserId().equals(fromFirstUser.getId())) {
                                    postReplyBaseInfo
                                            .setFromUserAvatar(fromFirstUser.getAvatar())
                                            .setFromUserNickname(fromFirstUser.getNickname());
                                }
                            }
                            List<UserBaseInfo> toUserBaseInfoList = replyUserBaseInfos.stream().filter(
                                    replyUserBaseInfo -> replyUserBaseInfo.getId().equals(toUserId)
                            ).collect(Collectors.toList());
                            if (!toUserBaseInfoList.isEmpty()) {
                                UserBaseInfo toUser = toUserBaseInfoList.get(0);
                                postReplyBaseInfo
                                        .setToUserAvatar(toUser.getAvatar())
                                        .setToUserNickname(toUser.getNickname()); // 回复对象
                            } else {
                                // 如果是一级回复的用户
                                if (fromFirstUser != null && postReplyBaseInfo.getToUserId().equals(fromFirstUser.getId())) {
                                    postReplyBaseInfo
                                            .setToUserAvatar(fromFirstUser.getAvatar())
                                            .setToUserNickname(fromFirstUser.getNickname());
                                }
                            }
                        }
                    });
                }
            }
            postVo.setPostReplyVoList(replyVoList);
        }

        // List<PostJoiner>
        System.out.println("List<PostJoiner>");
        List<PostJoiner> postJoinerList =
                CommonUtil.getItemsInResultObject(postJoinerClient.getAcceptedPostJoinersWithPostIdAndPostType(id, type), PostJoiner.class);
        if (postJoinerList != null && ! postJoinerList.isEmpty()) {
            List<String> joinerIds = postJoinerList.stream().map(PostJoiner::getUserId).collect(Collectors.toList());
            System.out.println(joinerIds);
            List<UserBaseInfo> joinerBaseInfos = CommonUtil.getItemsInResultObject(
                    userClient.getUserBaseInfosByIds(joinerIds), UserBaseInfo.class);
            if (joinerBaseInfos != null) {
                postJoinerList.stream().forEach(joiner -> {
                    UserBaseInfo correctJoinerBaseInfo = joinerBaseInfos.stream().filter(
                            joinerBaseInfo -> joinerBaseInfo.getId().equals(joiner.getUserId())
                    ).collect(Collectors.toList()).get(0);
                    joiner
                            .setUserAvatar(correctJoinerBaseInfo.getAvatar())
                            .setUserNickname(correctJoinerBaseInfo.getNickname());
                });
            }
            postVo.setPostJoinerList(postJoinerList);
        }

         return postVo;
    }

}
